package cn.liziguo.tank.factory;

import cn.liziguo.tank.config.GameConfig;
import cn.liziguo.tank.constants.*;
import cn.liziguo.tank.script.BaseTankComponent;
import cn.liziguo.tank.script.BulletComponent;
import com.almasb.fxgl.dsl.FXGL;
import com.almasb.fxgl.entity.Entity;
import com.almasb.fxgl.entity.SpawnData;
import com.almasb.fxgl.entity.components.CollidableComponent;
import com.almasb.fxgl.physics.BoundingShape;
import com.almasb.fxgl.texture.AnimatedTexture;
import com.almasb.fxgl.texture.AnimationChannel;
import javafx.util.Duration;

/**
 * @author Liziguo
 * @date 2022-07-09 23:31:20
 */
public final class BulletFactory {

    public static Entity createBullet(SpawnData data, BaseTankComponent baseTankComponent, CollidableComponent collidableComponent) {
        data.put(PropertyConst.BULLET_TYPE, BulletType.NORMAL);
        Entity entity = FXGL
                .entityBuilder(data)
                .type(GameEnum.BULLET)
                .viewWithBBox(GameConfig.getBulletImageByLevel(baseTankComponent.bulletLevel))
                .with(new BulletComponent(baseTankComponent))
                .with(collidableComponent)
                .build();
        entity.setPosition(baseTankComponent.getEntity().getCenter().subtract(entity.getWidth() / 2, entity.getHeight() / 2));
        return entity;
    }

    public static void createPlayerBullet(BaseTankComponent baseTankComponent) {
        FXGL.play(AudioConst.NORMAL_FIRE);

        SpawnData data = new SpawnData();
        data.put(PropertyConst.CAMP, CampEnum.PLAYER);

        CollidableComponent collidableComponent = new CollidableComponent(true);
        collidableComponent.addIgnoredType(GameEnum.PLAYER);

        FXGL.getGameWorld().addEntity(createBullet(data, baseTankComponent, collidableComponent));
    }

    public static void createPlayerBulletPlus(BaseTankComponent baseTankComponent) {
        FXGL.play(AudioConst.NORMAL_FIRE);

        SpawnData data = new SpawnData();
        data.put(PropertyConst.CAMP, CampEnum.PLAYER);

        CollidableComponent collidableComponent = new CollidableComponent(true);
        collidableComponent.addIgnoredType(GameEnum.PLAYER);

        createBulletPlus(baseTankComponent, data, collidableComponent);
    }

    public static void createEnemyBullet(BaseTankComponent baseTankComponent) {
        FXGL.play(AudioConst.NORMAL_FIRE);

        SpawnData data = new SpawnData();
        data.put(PropertyConst.CAMP, CampEnum.ENEMY);

        CollidableComponent collidableComponent = new CollidableComponent(true);
        collidableComponent.addIgnoredType(GameEnum.ENEMY);

        FXGL.getGameWorld().addEntity(createBullet(data, baseTankComponent, collidableComponent));
    }


    public static void createEnemyBulletPlus(BaseTankComponent baseTankComponent) {
        FXGL.play(AudioConst.NORMAL_FIRE);

        SpawnData data = new SpawnData();
        data.put(PropertyConst.CAMP, CampEnum.ENEMY);

        CollidableComponent collidableComponent = new CollidableComponent(true);
        collidableComponent.addIgnoredType(GameEnum.ENEMY);

        createBulletPlus(baseTankComponent, data, collidableComponent);
    }

    private static void createBulletPlus(BaseTankComponent baseTankComponent, SpawnData data, CollidableComponent collidableComponent) {
        final int width = 30;
        final int height = 40;

        data.put(PropertyConst.BULLET_TYPE, BulletType.PLUS);

        AnimationChannel animationChannel = new AnimationChannel(FXGL.image(ImageConst.BULLET_SKILL), Duration.seconds(.25), 4);
        AnimatedTexture ac = new AnimatedTexture(animationChannel);

        Entity entity = FXGL
                .entityBuilder(data)
                .type(GameEnum.BULLET)
                .bbox(BoundingShape.box(width, height))
                .view(ac.loop())
                .with(collidableComponent)
                .with(new BulletComponent(GameConfig.BULLET_LEVEL_MAX, GameConfig.BULLET_PLUS_ATTACK, 1200, baseTankComponent.vector))
                .build();

        ac.setTranslateX(entity.getWidth() / 2 - ac.getFitWidth() / 2);
        ac.setTranslateY(-ac.getFitHeight() / 5);
        entity.setPosition(baseTankComponent.getEntity().getCenter().subtract(entity.getWidth() / 2, entity.getHeight() / 2));
        FXGL.getGameWorld().addEntity(entity);
    }
}
